-- 树的广度搜索优先
-- 广度搜索优先的情况下某个方格如果周围一圈没有雷（计数为0）则可以自动打开
-- 难度在于雷的密度而不在于个数（如果10*10，有10个雷，密度相当于10%，有较多空隙）
-- 游戏重置未做，可添加操作栏，用以选择难度，显示个数，重新开始等
function love.load()
    cubeSize = 30
    level = 10 -- max 50
    winSize = (cubeSize+5) * level + 5
    love.window.setMode(winSize, winSize)
    cubeArray = {}
    countArray = {}
    curX = nil
    curY = nil
    down1 = 0
    gameover = false
    gamewin = false
    resetGame()
end

function resetGame()
    -- cubeArray = {}
    -- countArray = {}
    -- curX = nil
    -- curY = nil
    -- down1 = 0
    -- gameover = false
    -- gamewin = false

    for i=1,level do
        cubeArray[i] = {}
        for j = 1,level do
            cubeArray[i][j] = 0 -- 0原始状态，1打开状态，2雷，3标记无雷，4标记有雷，5检查无雷，6检查有雷
        end
    end
    local count = level
    repeat
        local x = love.math.random(1,level)
        local y = love.math.random(1,level)
        if cubeArray[x][y] ~= 2 then
            cubeArray[x][y] = 2
            count = count - 1
        end
    until count == 0
    for i=1,level do
        countArray[i] = {}
        for j = 1,level do
            countArray[i][j] = countArea(i,j)
        end
    end
end

function love.mousepressed( x, y, button, istouch, presses )
    for i=1,level do
        if x >= getX(i) and x <= getX(i) + cubeSize then
            curX = i
            for j = 1,level do
                if y >= getY(j) and y <= getY(j) + cubeSize then
                    curY = j
                    break
                end
            end
        end
    end
    if curX == nil and curY == nil then
        return
    end
    local val =  cubeArray[curX][curY]
    if button == 2 and val == 0 then
        cubeArray[curX][curY] = 3
    end
    if button == 2 and val == 3 then
        cubeArray[curX][curY] = 0
    end

    if button == 2 and val == 2 then
        cubeArray[curX][curY] = 4
    end
    if button == 2 and val == 4 then
        cubeArray[curX][curY] = 2
    end

    if button == 1 then
        if cubeArray[curX][curY] == 3 or cubeArray[curX][curY] == 4 then
            return
        elseif cubeArray[curX][curY] == 2 then
            gameover = true
        else
            cubeArray[curX][curY] = 5
            -- countArray[curX][curY] = countArea(curX,curY)
        end
    end
end

function love.update(dt)
    down1 = love.mouse.isDown(1)
    down2 = love.mouse.isDown(2)
    if curX ~= nil and curY ~= nil then
        if down1 and down2 then
            checkArea(curX,curY)
        end
    end
    if not down1 and not down2 then
        resetCube()
    end
    local count = 0
    for i=1,level do
        for j = 1,level do
            if cubeArray[i][j] == 2 then
                count = count + 1
            end
        end
    end
    if count == 0 then
        gamewin = true
    end
end

function love.draw()
    if gameover then
        drawGameOver()
        return
    end
    if gamewin then
        drawGameWin()
    end
    for i=1,level do
        for j = 1,level do
            if cubeArray[i][j] == 0 or cubeArray[i][j] == 2 then
                drawCube(i,j,{1,1,1}) -- 白色
            elseif cubeArray[i][j] == 5 or cubeArray[i][j] == 6 then
                drawCube(i,j,{0,1,1}) -- 淡蓝色
            elseif cubeArray[i][j] == 3 or cubeArray[i][j] == 4 then
                drawCube(i,j,{1,0,0}) -- 红色
            end
            if cubeArray[i][j] == 1 then
                drawCube(i,j,{1,1,0.5}) -- 淡黄色
                if countArray[i][j] ~= 0 then
                    love.graphics.print(countArray[i][j],getX(i)+cubeSize/2,getY(j))
                end
            end
        end
    end

    
end

function drawGameOver()
    love.graphics.setColor(1,0,1)
    love.graphics.print("Game Over!",winSize/2,winSize/2)
end

function drawGameWin()
    love.graphics.setColor(1,0,1)
    love.graphics.print("You Win!",winSize/2,winSize/2)
end

function checkArea(curX,curY)
    startX = curX - 1
    endX = curX + 1
    startY = curY - 1
    endY = curY + 1
    for i = startX,endX do
        for j = startY,endY do
            execCheckArea(i,j)
            -- countArray[i][j] = countArea(i,j)
        end
    end
end

function execCheckArea(i,j)
    if i >= 1 and j >= 1 and i<=level and j<=level then
        if cubeArray[i][j] == 2 then
            cubeArray[i][j] = 6
        end
        if cubeArray[i][j] ==0 then
            cubeArray[i][j] = 5
        end
    end
end

function countArea(i,j)
    local count = 0
    for ii = i - 1,i + 1 do
        for jj = j - 1,j + 1 do
            if ii >= 1 and jj >= 1 and ii<=level and jj<=level and (cubeArray[ii][jj] == 2 or cubeArray[ii][jj] == 4) then
                count = count + 1
            end
        end
    end
    return count
end

function clearCountArea(i,j)
    for ii = i - 1,i + 1 do
        for jj = j - 1,j + 1 do
            if ii >= 1 and jj >= 1 and ii<=level and jj<=level then
                countArray[ii][jj] = -1
            end
        end
    end
end

-- function countArea2()
--     for i=1,level do
--         countArray[i] = {}
--         for j = 1,level do
--             if cubeArray[i][j] == 4 then
--                 countArray[i][j] = -1
--             else
--                 local count = 0
--                 for ii = i - 1,i + 1 do
--                     for jj = j - 1,j + 1 do
--                         if ii >= 1 and jj >= 1 and ii<=level and jj<=level and cubeArray[ii][jj] == 4 then
--                             count = count + 1
--                         end
--                     end
--                 end
--                 countArray[i][j] = count
--             end
--         end
--     end
-- end

-- 如下方法已被上面替代！
-- function checkArea(curX,curY)
--     local val = 1
--     cubeArray[curX][curY] = val
--     if curX-1 >= 1 then
--         if cubeArray[curX-1][curY] == 0 then
--             cubeArray[curX-1][curY] = val
--         end
--         if curY-1 >= 1 and cubeArray[curX-1][curY-1] == 0 then
--             cubeArray[curX-1][curY-1] = val
--         end
--         if curY+1 <= level and cubeArray[curX-1][curY+1] == 0 then
--             cubeArray[curX-1][curY+1] = val    
--         end
--     end
--     if curX+1 <= level then
--         if curY-1 >= 1 and cubeArray[curX+1][curY-1]==0 then
--             cubeArray[curX+1][curY-1] = val
--         end
--         if cubeArray[curX+1][curY] == 0 then
--             cubeArray[curX+1][curY] = val
--         end
--         if curY+1 <= level and cubeArray[curX+1][curY+1] == 0 then
--             cubeArray[curX+1][curY+1] = val
--         end
--     end
--     if curY-1 >= 1 and cubeArray[curX][curY-1]==0 then
--         cubeArray[curX][curY-1] = val
--     end
--     if curY+1 <= level and cubeArray[curX][curY+1]==0 then
--         cubeArray[curX][curY+1] = val
--     end
-- end

function changeState(curX,curY,val)
    cubeArray[curX][curY] = val
end

function resetCube()
    for i=1,level do
        for j = 1,level do
            if cubeArray[i][j] == 5 then
                cubeArray[i][j] = 1
            end
            if cubeArray[i][j] == 6 then
                cubeArray[i][j] = 2
            end
        end
    end
end

function love.keypressed(key, scancode, isrepeat)
  if key == "escape" then
     love.event.quit()
  end
  if key == "r" and gameover == true then
    resetGame() 
 end
end

function drawCube(i,j,color)
    love.graphics.setColor(color)
    love.graphics.rectangle("fill",getX(i),getY(j),cubeSize,cubeSize)
    love.graphics.setColor({0,0,0})
    -- love.graphics.print(cubeArray[i][j],getX(i),getY(j))
end

function getX(i)
    return 5 + (cubeSize+5) * (i - 1)
end

function getY(j)
    return 5 + (cubeSize+5) * (j - 1)
end

